package controllers

import (
	"fmt"
	"net/http"
	"meman/sys/basic"
	"meman/models/auth"
	"meman/models/alert"
	"github.com/garyburd/redigo/redis"
	"meman/libs/utils"
	"errors"
	"github.com/labstack/echo"
	"github.com/chaosue/echo-sessions"
)

//service cfg中的常量
const MESSAGE_IN_LOG_FAILURE_KEY  = "event_center_message_in_failure_log"

//处理添加
func RedisInfo(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}
	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	conn,err := basic.RedisConn()
	defer conn.Close()
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis连接失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][RedisInfo]redis conn error:%s",username, err))
	}

	info,err := redis.String(conn.Do("info"))
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis信息获取失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][RedisInfo]redis get info error:%s",username, err))
	}


	c.Render(http.StatusOK, "redisInfo.tmpl", basic.H{
		"name":username,
		"data": info,
		"alert":alertInfo,
	})

	return nil

}

func MessageList(c echo.Context) error  {

	//session 使用
	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)
	if flashes := session.Flashes("alertInfo"); len(flashes) > 0 {
		alertInfo = flashes[0].(*alert.Alert)
	}
	session.Save()

	logger := basic.Logger{}


	conn,err := basic.RedisConn()
	defer conn.Close()
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis连接失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis conn error:%s",username,err))
	}


	indexStart := utils.TrimSpace(c.QueryParam("index_start"))
	indexEnd := utils.TrimSpace(c.QueryParam("index_end"))
	currentKey := utils.TrimSpace(c.QueryParam("key"))

	var listFailure []string
	if currentKey != "" && ( indexStart != "" || indexEnd != "" ) {

		if indexEnd == "" && indexStart != "" {
			indexEnd = indexStart
		}
		if indexStart == "" && indexEnd != "" {
			indexStart = indexEnd
		}

		listFailureTmp,err := redis.Values(conn.Do("lrange", currentKey, indexStart, indexEnd ))
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis获取失败列表失败:%s",err))}
			logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis lrange error:%s",username,err))
		}
		listFailure,err = convert(listFailureTmp)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis转换失败:%s",err))}
			logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis reflect []interface to []string error:%s",username, err))
		}
	}

	failureLogKeysTmp,err := redis.Values(conn.Do("keys", MESSAGE_IN_LOG_FAILURE_KEY+"*"))
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis获取keys失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis get keys error:%s",username,err))
	}
	failureLogKeys,err := convert(failureLogKeysTmp)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis转换失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis reflect []interface to []string error:%s",username,err))
	}
	failureLogKeysMap := make(map[string]int)
	for _,v := range failureLogKeys  {
		len, err := redis.Int(conn.Do("lLen", v))
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis获取长度%s失败:%s",v,err))}
			logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis get lLen error:%s",username,err))
		}
		failureLogKeysMap[v] = len
	}



	c.Render(http.StatusOK, "messageList.tmpl", basic.H{
		"name":username,
		"failureLogKeys":failureLogKeysMap,
		"listFailure": listFailure,
		"currentKey":currentKey,
		"alert":alertInfo,
	})

	return nil
}

func MessageListDel(c echo.Context) error  {

	session := sessions.Default(c)
	var username string
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	conn,err := basic.RedisConn()
	defer conn.Close()
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("redis连接失败:%s",err))}
		logger.WriteMsg("error", fmt.Sprintf("[%s][MessageList]redis conn error:%s",username,err))
	}

	_,err = conn.Do("del", MESSAGE_IN_LOG_FAILURE_KEY+"_recover_lock")
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("[%s][MessageListDel]redis删除指定值失败:%s",username, err))}
		logger.WriteMsg("error", fmt.Sprintf("MessageList: redis del error:%s",err))
	}

	session.AddFlash(alertInfo, "alertInfo")
	session.Save()


	c.Redirect(http.StatusFound,"/RedisInfo/MessageList")

	return err
}

func convert(args []interface{}) ([]string,error)  {
	var slice []string
	for _, v := range args {
		if value, ok := v.([]byte); ok {
			slice = append(slice, string(value))
		}else {
			return nil ,errors.New("不能类型判断为[]byte类型")
		}
	}
	return slice, nil
}
